<template>
    <main-page>
        <el-row style="height: 32px; padding: 5px">
            <el-col :span="6">
                <el-select v-model="properties.data.connection" value-key="id" @change="properties.handle.change">
                    <el-option v-for="item in properties.data.connections" :key="item.id" :label="item.title" :value="item">
                        <span style="float: left">{{item.title}}</span>
                        <span style="float: right; color: var(--el-text-color-secondary); font-size: 13px; margin-left: 50px">{{ item.server }}</span>
                    </el-option>
                </el-select>
            </el-col>
            <el-col :span="18" style="display: flex;justify-content: flex-end;">
                <el-button @click="properties.handle.edit('create')">创建</el-button>
                <el-button @click="properties.handle.edit('update', properties.data.connection)" :disabled="properties.data.isConnected || properties.data.connection === null">修改</el-button>
                <el-button @click="properties.handle.disconnect()" v-if="properties.data.isConnected">断开</el-button>
                <el-button @click="properties.handle.connection()" v-else :disabled="properties.data.connection === null">连接</el-button>
                <el-button @click="properties.handle.delete()" :disabled="properties.data.isConnected || properties.data.connection === null" type="danger">删除</el-button>
            </el-col>
        </el-row>

        <el-row :gutter="2" v-loading="properties.loading" v-if="properties.data.isConnected"
                style="margin-top: 10px; padding: 5px; height: calc(100% - 32px - 10px); width: calc(100% - 2px)">
            <el-col :span="6">
                <el-card style="height: 100%" shadow="always">
                    <template #header>
                        <el-input v-model="properties.data.keyword" clearable placeholder="输入关键字自动搜索" prefix-icon="search"></el-input>
                    </template>
                    <el-scrollbar>
                        <el-tree ref="treeRef"
                                 :filter-node-method="properties.handle.filterNode"
                                 :load="properties.handle.load"
                                 :props="properties.data.props"
                                 accordion
                                 highlight-current
                                 lazy
                                 node-key="id"
                                 @current-change="properties.handle.currentChange"/>
                    </el-scrollbar>
                </el-card>
            </el-col>
            <el-col :span="18">
                <el-card style="height: 100%" body-style="padding: var(--el-card-padding) var(--el-card-padding) 0" shadow="always">
                    <template #header>
                        <el-input :model-value="properties.data?.detail?.path || '/'" class="input-border__none" readonly/>
                    </template>
                    <div v-if="properties.data.detail">
                        <div style="width: 100%; display: flex;justify-content: space-between;">
                            <el-popover :show-after="500" placement="bottom-start" trigger="hover" width="90vh">
                                <template #reference>
                                    <el-link :underline="false" type="primary">详细信息</el-link>
                                </template>
                                <template #default>
                                    <el-form label-position="right" label-width="150px">
                                        <el-row>
                                            <el-col :span="12">
                                                <el-form-item label="修改时间">
                                                    <el-tooltip content="表示节点最后一次被修改的时间" placement="right-end">
                                                        <el-link :underline="false" type="primary">
                                                            {{ properties.data.detail.stat?.mtime === 0 ? 0 : new Date(properties.data.detail.stat?.mtime).toLocaleString() }}
                                                        </el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                            <el-col :span="12">
                                                <el-form-item label="创建时间">
                                                    <el-tooltip content="表示节点创建时间" placement="right-end">
                                                        <el-link :underline="false" type="primary">
                                                            {{ properties.data.detail.stat?.ctime === 0 ? 0 : new Date(properties.data.detail.stat?.ctime).toLocaleString() }}
                                                        </el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                        </el-row>

                                        <el-row>
                                            <el-col :span="12">
                                                <el-form-item label="节点修改时事务ID">
                                                    <el-tooltip content="表示节点最后一次被修改时的事务 ID" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.mzxid }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                            <el-col :span="12">
                                                <el-form-item label="ACL版本号">
                                                    <el-tooltip content="表示当前节点的ACL版本" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.aversion }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                        </el-row>

                                        <el-row>
                                            <el-col :span="12">
                                                <el-form-item label="子节点修改时事务ID">
                                                    <el-tooltip content="表示该节点的子节点列表最后一次被修改时的事务 ID,只有子节点列表变更才会更新 pZxid，子节点内容变更不会更新"
                                                                placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.pzxid }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                            <el-col :span="12">
                                                <el-form-item label="数据版本号">
                                                    <el-tooltip content="表示当前节点内容版本号" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.version }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                        </el-row>

                                        <el-row>
                                            <el-col :span="12">
                                                <el-form-item label="创建时事务ID">
                                                    <el-tooltip content="表示节点被创建时的事务 ID" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.czxid }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                            <el-col :span="12">
                                                <el-form-item label="节点版本号">
                                                    <el-tooltip content="表示当前节点子节点的版本" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.cversion }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                        </el-row>

                                        <el-row>
                                            <el-col :span="12">
                                                <el-form-item label="数据长度">
                                                    <el-tooltip content="表示数据长度" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.dataLength }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                            <el-col :span="12">
                                                <el-form-item label="子节点数量">
                                                    <el-tooltip content="表示子节点数" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.numChildren }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                        </el-row>

                                        <el-row>
                                            <el-col :span="12">
                                                <el-form-item label="临时所有者" trigger="click">
                                                    <el-tooltip content="表示创建该临时节点时的会话 sessionID，如果是持久性节点那么值为 0" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.stat?.ephemeralOwner }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                            <el-col :span="12">
                                                <el-form-item label="权限" trigger="click">
                                                    <el-tooltip content="表示对当前节点拥有的权限" placement="right-end">
                                                        <el-link :underline="false" type="primary">{{ properties.data.detail.acl }}</el-link>
                                                    </el-tooltip>
                                                </el-form-item>
                                            </el-col>
                                        </el-row>
                                    </el-form>
                                </template>
                            </el-popover>
                            <el-button-group v-show="properties.data.detail.path">
                                <el-button icon="refresh" @click="properties.handle.buttonGroup('refresh')">刷新</el-button>
                                <el-button icon="check" @click="properties.handle.buttonGroup('update')">保存</el-button>
                                <el-button icon="plus" @click="properties.handle.buttonGroup('create')">子节点</el-button>
                                <el-button icon="delete" type="danger" @click="properties.handle.buttonGroup('delete')">删除</el-button>
                            </el-button-group>
                        </div>

                        <el-input v-model:model-value="properties.data.detail.data" :autosize="{ minRows: 36, maxRows: 36 }" resize="none" style="margin-top: 15px" type="textarea"/>
                    </div>
                </el-card>
            </el-col>
        </el-row>

        <el-dialog v-model="nodeDataForm.visible" width="30%" title="添加子节点" append-to-body :show-close="false" destroy-on-close>
            <el-form ref="nodeDataFormRef" :model="nodeDataForm.form" :rules="nodeDataForm.rules" label-width="60px">
                <el-form-item label="路径">
                    <el-text style="width: 100%;font-size: 15px" truncated>{{ properties.data.detail.path || '/' }}</el-text>
                </el-form-item>
                <el-form-item label="名称" prop="name">
                    <el-input v-model="nodeDataForm.form.name" placeholder="子节点名称"/>
                </el-form-item>
                <el-form-item label="数据" prop="data">
                    <el-input v-model="nodeDataForm.form.data" :rows="10" placeholder="子节点数据内容" type="textarea"/>
                </el-form-item>
            </el-form>
            <div style="display: flex;justify-content: flex-end;">
                <el-button @click="nodeDataForm.handle.close()">关闭</el-button>
                <el-button type="primary" @click="nodeDataForm.handle.submit()" :loading="nodeDataForm.loading">确定</el-button>
            </div>
        </el-dialog>

        <edit ref="editRef" :owner="properties.data.params.owner"/>
    </main-page>
</template>
<script>
import {defineComponent, ref, reactive, getCurrentInstance, watch, onBeforeMount} from "vue";
import {service} from "@/utils";
import store from "@/store";
import Edit from './edit.vue'

export default defineComponent({
    components: {Edit},
    setup() {
        const {proxy} = getCurrentInstance();
        const {user} = store.userStore;
        const editRef = ref();
        const treeRef = ref();
        const properties = reactive({
            loading: false,
            data: {
                uid: null,
                params: {
                    owner: user.userId
                },
                keyword: null,
                connection: null,
                isConnected: false,
                connections: [],
                detail: null,
                props: {
                    isLeaf: 'leaf'
                },
            },
            handle: {
                connections: () => {
                    service.get('/zookeeper/find', properties.data.params).then(({data}) => {
                        properties.data.connections = data || [];
                        if (properties.data.connection) {
                            // 修改后当前下拉选中的对象信息不会及时更新，故需要手动更新
                            properties.data.connection = properties.data.connections.find(item => item.id === properties.data.connection.id)
                        }
                    })
                },
                change: () => {
                    service.get(`/zookeeper/exists/${properties.data.uid}`, {
                        id: properties.data.connection.id
                    }).then(({data}) => properties.data.isConnected = data)
                },
                // 创建/修改连接信息
                edit: (action, data) => {
                    editRef.value.open({
                        data: data,
                        type: action === 'create'? 'post':'put',
                        confirm: (resolve, form, operate) => {
                            service[operate](`/zookeeper/edit`, form).then(({code}) => {
                                if (code === 200) {
                                    properties.handle.connections()
                                }
                                resolve(code);
                            })
                        }
                    });
                },
                // 删除连接信息
                delete: ()=>{
                    proxy.$confirm(`确定删除[${properties.data.connection.title}]连接信息?`, '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(() => {
                        properties.loading = true;
                        service.delete(`/zookeeper/delete`, properties.data.connection)
                                .then(({code}) => code === 200 && properties.handle.connections())
                                .finally(() => properties.loading = false)
                    }).catch(() => {});

                },
                // 建立连接
                connection: () => {
                    const loadingInstance = proxy.$loading({text: `${properties.data.connection.title}正在连接...`})
                    service.post(`/zookeeper/connection/${properties.data.uid}`, properties.data.connection, {timeout: 30000}).then(({code})=> {
                        if (code === 200) {
                            properties.data.isConnected = true;
                        }
                    }).finally(() => loadingInstance.close())
                },
                //断开连接
                disconnect: () => {
                    const loadingInstance = proxy.$loading({text: `${properties.data.connection.title}正在断开连接...`})
                    service.delete(`/zookeeper/close/${properties.data.uid}`, properties.data.connection).then(({code}) =>{
                        if (code === 200) {
                            properties.data.isConnected = false;
                        }
                    }).finally(()=> loadingInstance.close());
                },
                // 过滤筛选节点
                filterNode: (value, data) => {
                    return !value || data.label.includes(value)
                },
                // 懒加载数据
                load: ({level, data}, resolve) => {
                    service.post(`/zookeeper/children/${properties.data.uid}`, {
                        id: properties.data.connection.id,
                        forPath: level === 0? properties.data.connection.forPath:data.path
                    }).then(({code, data}) => resolve(code === 200? data:[])).catch(()=> resolve([]))
                },
                //获取当前节点详细信息
                currentChange: (data) => {
                    let {id, authorization} = properties.data.connection;
                    service.post(`/zookeeper/detail/${properties.data.uid}`, {
                        id,
                        authorization,
                        forPath: data.path
                    }).then(({code, data}) => {
                        if (code === 200) {
                            properties.data.detail = data
                        }
                    });
                },
                //节点操作按钮
                buttonGroup: (command, item) => {
                    switch (command) {
                        case 'refresh':
                            properties.loading = true;
                            service.post(`/zookeeper/refresh/${properties.data.uid}`, {
                                id: properties.data.connection.id,
                                forPath: properties.data.detail.path,
                            }).then(({code, data, level})=> {
                                let node = treeRef.value.getNode(data.id)
                                if (code === 200) {
                                    node.setData(data);
                                    node.expand();
                                } else if (['NONODE'].includes(level)){
                                    treeRef.value.remove(node)
                                }
                                properties.handle.currentChange(node.data)
                            }).finally(() => properties.loading = false)
                            break;
                        case 'create':
                            nodeDataForm.visible = true;
                            break;
                        case 'update':
                            properties.loading = true;
                            service.put(`/zookeeper/saveData/${properties.data.uid}`, {
                                id: properties.data.connection.id,
                                forPath: properties.data.detail.path,
                                data: properties.data.detail.data,
                                version: properties.data.detail.stat.version
                            }).then(({code, data, level})=>{
                                let node = treeRef.value.getNode(data.id)
                                if (code === 200) {
                                    data.children = node.childNodes.map(n => n.data);
                                    node.setData(data)
                                    properties.data.detail.stat = data.stat
                                } else if (['NONODE'].includes(level)){
                                    treeRef.value.remove(node)
                                }
                            }).finally(() => properties.loading = false)
                            break;
                        case 'delete':
                            proxy.$confirm(`确定对删除[${properties.data.detail.path}]节点,包括其所有子节点?`, '提示', {
                                cancelButtonText: '取消',
                                confirmButtonText: '确定'
                            }).then(() => {
                                properties.loading = true;
                                service.post(`/zookeeper/deleteNode/${properties.data.uid}`, {
                                    id: properties.data.connection.id,
                                    forPath: properties.data.detail.path,
                                }).then(({code})=>{
                                    if (code === 200){
                                        let node = treeRef.value.getNode(properties.data.detail.id);
                                        treeRef.value.remove(node)
                                    }
                                }).finally(() => properties.loading = false)
                            }).catch(() => {
                                properties.loading = false;
                            });
                            break;
                    }
                }
            }
        })

        //创建子节点
        const nodeDataFormRef = ref();
        const nodeDataForm = reactive({
            visible: false,
            loading: false,
            form: {
                name: null,
                data: null
            },
            handle: {
                close: () => {
                    nodeDataFormRef.value.resetFields();
                    nodeDataForm.visible = false;
                },
                submit: () => {
                    nodeDataFormRef.value.validate((valid) => {
                        if (valid) {
                            nodeDataForm.loading = true;
                            service.post(`/zookeeper/createNode/${properties.data.uid}`, {
                                id: properties.data.connection.id,
                                forPath: (properties.data.detail.path === '/'? '/' : properties.data.detail.path + '/') + nodeDataForm.form.name,
                                data: nodeDataForm.form.data,
                            }).then(({code, data}) => {
                                if (code === 200) {
                                    let cn = treeRef.value.getNode(properties.data.detail.id);
                                    if (!cn.loaded) {
                                        cn.expand(); // 触发loadHandle函数，重新加载节点数据
                                    } else {
                                        treeRef.value.append(data, cn)
                                    }
                                    nodeDataForm.handle.close();
                                }
                            }).finally(() => nodeDataForm.loading = false)
                        }
                    });
                }
            }
        })


        onBeforeMount(() => {
            let {query, meta} = proxy.$router.currentRoute.value;
            properties.data.uid = query.uid;
            window.document.title = meta.title;
            properties.handle.connections()
        })

        watch(() => properties.data.keyword, (v) => treeRef.value?.filter(v))

        return {
            editRef, treeRef, nodeDataFormRef,
            properties, nodeDataForm,
        };
    }
});
</script>
<style scoped>

</style>